package com.cloudatum.service;

import com.cloudatum.mobile.MobileUtil;
import com.cloudatum.mobile.PhoneRegion;
import com.cloudatum.redis.RedisUtil;
import com.cloudatum.utils.Constants;
import com.cloudatum.utils.PhoneRegionCheckUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 订单处理逻辑
 * Created by zhoujian on 2015/11/2.
 */
@Service
public class OrderService {

    static Logger logger = LoggerFactory.getLogger(OrderService.class);

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private VerificationCodeService verificationCodeService;


    /**
     * 进入订单
     * @param sessionId sessionId
     * @return code 0:未开始 -1:超过入口人数限制
     */
    public Map inOrder(String sessionId){
        Jedis jedis = null;
        Map<String,String> map = new HashMap<>();
        map.put("sessionId", sessionId);
        map.put("code","0");
        boolean isAllow = false;
        try{
            jedis = RedisUtil.getJedis();
            String beginTime = jedis.hget(Constants.CURRENT_MIAOSHA, Constants.BEGIN_TIME);
            String currentMiaoId = jedis.hget(Constants.CURRENT_MIAOSHA, Constants.CURRENT_MIAOSHA_ID);
            Date beginTimeDate = new Date(Long.parseLong(beginTime));
            jedis.incr(Constants.COUNT_INORDER_ALL + currentMiaoId);

            //判断是否开始
            if (beginTimeDate.compareTo(new Date()) >= 0) {
                return map;
            }

            String session = jedis.get(sessionId + currentMiaoId);
            long currentPeopleLimit = Long.parseLong(jedis.hget(Constants.CURRENT_MIAOSHA, Constants.PEOPLE_LIMIT));

            if (currentPeopleLimit <= 0 && currentPeopleLimit != Constants.UN_LIMIT_PEOPLE){
                map.put("code","-1");
                return map;
            }

            Map<String,String> verification = verificationCodeService.randCacheOne();
            if (null == verification ){
                map.put("code","-1");
                return map;
            }
            String answer = verification.get(Constants.VERIFICATION_ANSWER);
            if (null != session){
                isAllow = true;
            }else {
                if (currentPeopleLimit != -10000) {
                    currentPeopleLimit = jedis.hincrBy(Constants.CURRENT_MIAOSHA, Constants.PEOPLE_LIMIT, -1);
                    if (currentPeopleLimit >= 0) {
                        isAllow = true;
                    }else {
                        map.put("code","-1");
                    }
                }else {
                    isAllow = true;
                }
            }

            if (isAllow){
                map.put("verificationImg",verification.get(Constants.VERIFICATION_IMG));
                map.put("code","1");
                //将这个sessionId放入缓存，有效期60秒，绑定验证码
                jedis.setex(sessionId + currentMiaoId, 60, "1");
                jedis.setex(Constants.VERIFICATION_CODE + sessionId + currentMiaoId, 60, answer);
            }
        }catch (Exception e){
            return map;
        }finally {
            RedisUtil.returnResource(jedis);
        }
        return map;
    }

    /**
     * 下订单
     * @param code 验证码
     * @param phone 手机
     * @param sessionId sessionId
     * @param paraMap 把订单uuid传到controller用的容器
     * @return  1 成功
     *          0 活动未开始
     *         -1 手机归属地错误
     *         -2 验证码错误
     *         -3 产品剩余不足
     *         -4 存数据库时发生错误
     *         -5 sessionId缓存中不存在
     *         -6 余量不足
     *         -7 手机号已经购买过了
     */
    public int doOrder(String sessionId,String code,String phone,Map<String,String> paraMap) {
        Jedis jedis = RedisUtil.getJedis();

        String currentMiaoShaId;
        String currentGoodsId;
        try {
            currentMiaoShaId = jedis.hget(Constants.CURRENT_MIAOSHA, Constants.CURRENT_MIAOSHA_ID);
            currentGoodsId = jedis.hget(Constants.CURRENT_MIAOSHA, Constants.CURRENT_GOODS_ID);
            String beginTime = jedis.hget(Constants.CURRENT_MIAOSHA, Constants.BEGIN_TIME);
            String cacheSessionId = jedis.get(sessionId +currentMiaoShaId);
            boolean isBought = jedis.sismember(Constants.PHONE_HAS_BOUGHT,phone);
            Date beginTimeDate = new Date(Long.parseLong(beginTime));

            //判断是否开始
            if (beginTimeDate.compareTo(new Date()) > 0) {
                return 0;
            }

            if (isBought){
                return -7;
            }

            //是否同一个session
            if (StringUtils.isEmpty(cacheSessionId)) {
                return -5;
            }

            //判断归属地
            PhoneRegion phoneRegion = MobileUtil.queryMobileAttribution(phone);
            if (!PhoneRegionCheckUtil.regionCheck(phoneRegion, jedis.get(Constants.REGION_LIMIT + currentMiaoShaId))) {
                return -1;
            }

            //检查验证码
            String cacheCode = jedis.get(Constants.VERIFICATION_CODE + sessionId + currentMiaoShaId);
            if (!StringUtils.equals(code,cacheCode)) {
                return -2;
            }

            //检查库存
            //这个库存实际处理为real_stock字段
            int leftGoodsCounts = Integer.parseInt(jedis.hget(Constants.CURRENT_MIAOSHA, Constants.CURRENT_GOODS_REALSTOCK));
            if (leftGoodsCounts >= 0){
                long leftGoodsDecr = jedis.hincrBy(Constants.CURRENT_MIAOSHA, Constants.CURRENT_GOODS_REALSTOCK, -1);
                if (leftGoodsDecr >= 0) {
                    String uuid = UUID.randomUUID().toString();
                    int count = 0;
                    try {
                        count = orderMapper.insertOrder(uuid, phone, currentMiaoShaId, currentGoodsId);
                    }catch (Exception e){
                        logger.error("==> Mybatis Catch exception {} ==> {}",e.getClass().getName(),e.getMessage());
                    }
                    if (1 != count) {
                        logger.error("==> add goods capacity!");
                        jedis.hincrBy(Constants.CURRENT_MIAOSHA, Constants.CURRENT_GOODS_REALSTOCK,1);
                    }
                    paraMap.put("uuid",uuid);
                    jedis.sadd(Constants.PHONE_HAS_BOUGHT,phone);
                    return 1;
                }
            }else {
                return -3;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            RedisUtil.returnResource(jedis);
        }
        return -6;
    }

    /**
     * 完善订单
     * @param uuid 订单id
     * @param contact 联系人
     * @param address 地址
     * @param remark 备注
     * @return Map code 1 成功
     *                 -1 地址为空
     *                  0 uuid不存在
     *
     */
    public Map completeOrder(String uuid,String contact,String address, String remark){
        Map<String,String> map = new HashMap<>();
        int count = orderMapper.selectOrderByUUID(uuid);

        if (count <= 0){
            map.put("code","0");
            return map;
        }

        if (StringUtils.isEmpty(address)){
            map.put("code","-1");
            return map;
        }

        int result = orderMapper.completeOrder(uuid,contact,address,remark);

        if (result == 1){
            map.put("code","1");
        }else {
            map.put("code","0");
        }

        return map;
    }

}
